package cn.jinjimi.domain.data.imp;

import cn.jinjimi.app.AccountManager;
import cn.jinjimi.app.controller.event.AnalysisEvent;
import cn.jinjimi.app.controller.event.ArticleQuaryEvent;
import cn.jinjimi.app.controller.event.CollecCancleEvent;
import cn.jinjimi.app.controller.event.CollectEvent;
import cn.jinjimi.app.controller.event.CollectMyEvent;
import cn.jinjimi.app.controller.event.DataEvent;
import cn.jinjimi.app.controller.event.ShareCountEvent;
import cn.jinjimi.app.controller.event.ShareXrkEvent;
import cn.jinjimi.domain.data.Store;
import cn.jinjimi.domain.data.net.API;
import cn.jinjimi.domain.data.net.ReaderService;
import cn.jinjimi.domain.data.dto.ArticleAllListDTO;
import cn.jinjimi.domain.data.dto.ArticleListDTO;
import cn.jinjimi.domain.data.dto.ArticleRecommendListDTO;
import cn.jinjimi.domain.store.ReaderStore;
import cn.jinjimi.app.entity.Account;
import cn.jinjimi.app.entity.Article;
import cn.jinjimi.app.entity.ArticleMeta;
import cn.jinjimi.app.entity.SharedCount;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by zhenhua on 16/8/1.
 */
public class ReaderStoreImp extends Store implements ReaderStore {

    @Override
    public SharedCount fetchSharedCount() throws IOException {
        Response<SharedCount> response = API.create(ReaderService.class).getSharedCount().execute();

        return parseDataAndDispatchEvents(response, new ShareCountEvent());
    }

    @Override
    public Article recordShare(String articleId, String comment, String showAds) throws IOException {
        HashMap<String, String> params = new HashMap<String, String>();
        Account account = AccountManager.getInstance().getAccount();

        params.put("shared_record.sso_id", account.ssoid);
        params.put("shared_record.article_id", articleId);
        params.put("shared_record.opinion", comment == null ? "" : comment);  //no opinion anymore
        params.put("shared_record.uuid", account.uuid);
        params.put("shared_record.is_display_adv", showAds);

        Response<Article> response = API.create(ReaderService.class).share(params).execute();
        return parseDataAndDispatchEvents(response, new ShareXrkEvent());
    }

    @Override
    public Article collect(String ssoid, String articleId) throws IOException {
        return parseDataAndDispatchEvents(API.create(ReaderService.class).collect(ssoid, articleId).execute(),
                new CollectEvent());
    }

    @Override
    public boolean unCollect(String articleId) throws IOException {
        Response<ResponseBody> response = API.create(ReaderService.class).unCollect(articleId).execute();
        ResponseBody body = parseDataAndDispatchEvents(response, new CollecCancleEvent());
        return body != null;
    }

    @Override
    public ArticleMeta getArticleMetaData(String articleId) throws IOException {

        return parseDataAndDispatchEvents(
                API.create(ReaderService.class).getArticleMetaData(articleId,
                        AccountManager.getInstance().getAccount().ssoid).execute(),
                new ArticleQuaryEvent()
        );
    }

    @Override
    public List<Article> getCollects(String ssoid, int page, int limit) throws IOException {
        ArticleListDTO dto = parseDataAndDispatchEvents(
                API.create(ReaderService.class).getCollects(ssoid, page, limit).execute(),
                new CollectMyEvent()
        );

        return dto == null ? null : dto.getArticles();
    }

    @Override
    public List<Article> getArticlesOfWeek(String ssoid) throws IOException {
        final AnalysisEvent event = new AnalysisEvent();
        event.state = DataEvent.FAIL;
        API.create(ReaderService.class).getArticlesOfWeek(ssoid).enqueue(new Callback<ArticleListDTO>() {
            @Override
            public void onResponse(Call<ArticleListDTO> call, Response<ArticleListDTO> response) {
                if (response.isSuccessful()) {
                    ArticleListDTO dto = response.body();
                    if (dto != null && dto.getArticles() != null) {
                        event.state = DataEvent.SUCC;
                        HashMap<String, String> headers = new HashMap<>();
                        for (String name : response.headers().names()) {
                            headers.put(name, response.headers().get(name));
                        }
                        event.header = headers;
                        event.data = dto;
                    }
                }
                dispatch(event);
            }

            @Override
            public void onFailure(Call<ArticleListDTO> call, Throwable t) {
                dispatch(event);
            }
        });


        return event.data == null ? null : event.data.getArticles();
    }

    @Override
    public ArticleListDTO searchArticles(String title, int page, int limit) throws IOException {
        Response<ArticleListDTO> ret = API.create(ReaderService.class).searchArticles(title, page, limit).execute();
        ArticleListDTO mData = getHttpState(ret, new ArticleListDTO());
        return mData;
    }

    @Override
    public ArticleRecommendListDTO getRecommendArticleList(int offset, int limit) throws IOException {
        return getHttpState(API.create(ReaderService.class).getArticleRecommend(offset, limit).execute(), new ArticleRecommendListDTO());
    }

    @Override
    public ArticleAllListDTO getAllArticleList(int page, int limit) throws IOException {
        return getHttpState(API.create(ReaderService.class).getArticleAllList(page, limit).execute(), new ArticleAllListDTO());
    }
}
